package com.mlink.ai.chat.ui.fragment

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.adsdk.android.ads.nativead.NativeAdListener
import com.adsdk.android.ads.nativead.OxNativeAdHelper
import com.adsdk.android.ads.nativead.ViewBinder
import com.icekrvams.air.versionchecker.LocalVersionChecker
import com.mlink.ai.chat.AiChatApplication
import com.mlink.ai.chat.ads.AdUtils
import com.mlink.ai.chat.ads.adManager
import com.mlink.ai.chat.assistant.robot.R
import com.mlink.ai.chat.assistant.robot.databinding.DialogChatGuideBinding
import com.mlink.ai.chat.assistant.robot.databinding.FragmentChatBinding
import com.mlink.ai.chat.assistant.robot.databinding.LayoutMainBottomNavigationBinding
import com.mlink.ai.chat.constants.CHAT_GUIDANCE_ADDED_VERSION
import com.mlink.ai.chat.constants.KEY_CHAT_EXAMPLE
import com.mlink.ai.chat.constants.isFirstOpenApp
import com.mlink.ai.chat.ui.activity.BillingActivity
import com.mlink.ai.chat.ui.activity.HistoryActivity
import com.mlink.ai.chat.ui.activity.RecentListActivity
import com.mlink.ai.chat.ui.activity.chat.ChatNewActivity
import com.mlink.ai.chat.ui.adapter.ChatHistoryHomeAdapter
import com.mlink.ai.chat.ui.adapter.TopicPageAdapter
import com.mlink.ai.chat.ui.view.ChatNestedScrollView
import com.mlink.ai.chat.ui.viewmodel.RecentViewModel
import com.mlink.ai.chat.utils.*
import com.tencent.mmkv.MMKV


class ChatFragment : BaseFragment<FragmentChatBinding>() {

    private val appViewModel = AiChatApplication.app.appViewModel
    private val recentViewModel: RecentViewModel by viewModels()
    private var oxNativeAdHelper: OxNativeAdHelper? = null
    private lateinit var flashAnimator: ObjectAnimator
    private var exampleLoggedList = mutableListOf<String>() // 已经打点过的 example
    private var selectDialogFragment: SelectPhotoBottomDialogFragment? = null
    private lateinit var historyAdapter: ChatHistoryHomeAdapter

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initViews()
    }

    override fun getViewBinding(): FragmentChatBinding {
        return FragmentChatBinding.inflate(layoutInflater)
    }


    private fun initViews() {
        addRecentHistory()
        initTabLayout()
        appViewModel.getSubscribeLiveData().observe(viewLifecycleOwner) {
            if (!it) {
                binding.layoutRemove.llRemoveLimits.visibility = View.GONE
                binding.itemAds.visibility = View.VISIBLE
                if (binding.nativeAdContainer.childCount <= 0) {
                    oxNativeAdHelper = adManager.getMainNativeBannerAd()
                    if (oxNativeAdHelper == null) {
                        binding.ivFlash.visibility = View.VISIBLE
                        binding.nativeBannerPlaceholder.root.post {
                            playFlashAnimation()
                        }
                        loadNativeBanner()
                    } else {
                        showNativeBannerAd()
                    }
                } else {
                    binding.nativeAdContainer.visibility = View.VISIBLE
                    binding.ivFlash.visibility = View.GONE
                    binding.nativeBannerPlaceholder.root.visibility = View.GONE
                }
            } else {
                binding.layoutRemove.llRemoveLimits.visibility = View.GONE
                binding.ivFlash.visibility = View.GONE
                binding.itemAds.visibility = View.GONE
                cancelFlashAnimation()
            }
            isFirstOpenApp = false
        }

        binding.layoutRemove.llRemoveLimits.setOnClickListener {
            startActivity(Intent(requireContext(), BillingActivity::class.java).apply {
                putExtra(BillingActivity.KEY_VIP_TYPE, AnalyticsParams.HOME)
            })
        }

        val exampleImageText1 = resources.getString(R.string.example_image_chat_1)
        val exampleText5 = resources.getString(R.string.example_chat_5)
        val exampleText6 = resources.getString(R.string.example_chat_6)
        val exampleText7 = resources.getString(R.string.example_chat_7)
        val exampleText8 = resources.getString(R.string.example_chat_8)
        binding.exampleImageItem1.apply {
            exampleItemTv.text = exampleImageText1
            exampleItemIv.setImageResource(R.drawable.ic_examples_photo)
        }
        binding.exampleItem5.apply {
            exampleItemTv.text = exampleText5
        }
        binding.exampleItem6.apply {
            exampleItemTv.text = exampleText6
        }
        binding.exampleItem7.apply {
            exampleItemTv.text = exampleText7
        }
        binding.exampleItem8.apply {
            exampleItemTv.text = exampleText8
        }

        binding.exampleImageItem1.root.setOnClickListener {
            AnalyticsEvents.AC_CHAT_EXAMPLE_CLICK.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, requireContext().getEnglishString(R.string.example_image_chat_1))
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_PIC)
                }
            )
            doShowSelectDialogFragment(exampleImageText1)
        }
        binding.exampleItem5.root.setOnClickListener {
            AnalyticsEvents.AC_CHAT_EXAMPLE_CLICK.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, requireContext().getEnglishString(R.string.example_chat_5))
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            startActivity(Intent(requireContext(), ChatNewActivity::class.java).apply {
                putExtra(KEY_CHAT_EXAMPLE, exampleText5)
            })
        }
        binding.exampleItem6.root.setOnClickListener {
            AnalyticsEvents.AC_CHAT_EXAMPLE_CLICK.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, requireContext().getEnglishString(R.string.example_chat_6))
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            startActivity(Intent(requireContext(), ChatNewActivity::class.java).apply {
                putExtra(KEY_CHAT_EXAMPLE, exampleText6)
            })
        }
        binding.exampleItem7.root.setOnClickListener {
            AnalyticsEvents.AC_CHAT_EXAMPLE_CLICK.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, requireContext().getEnglishString(R.string.example_chat_7))
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            startActivity(Intent(requireContext(), ChatNewActivity::class.java).apply {
                putExtra(KEY_CHAT_EXAMPLE, exampleText7)
            })
        }
        binding.exampleItem8.root.setOnClickListener {
            AnalyticsEvents.AC_CHAT_EXAMPLE_CLICK.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, requireContext().getEnglishString(R.string.example_chat_8))
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            startActivity(Intent(requireContext(), ChatNewActivity::class.java).apply {
                putExtra(KEY_CHAT_EXAMPLE, exampleText8)
            })
        }

        binding.chatTv.setOnClickListener {
            AnalyticsEvents.AC_CHAT_PORTAL_CLICK.logEvent()
            startActivity(Intent(requireContext(), ChatNewActivity::class.java))
        }

        binding.sendIv.setOnClickListener {
            AnalyticsEvents.AC_CHAT_PORTAL_CLICK.logEvent()
            startActivity(Intent(requireContext(), ChatNewActivity::class.java))
        }

        binding.scrollview.setOnScrollChanged(object : ChatNestedScrollView.OnScrollChanged {
            override fun onScroll(left: Int, top: Int, oldLeft: Int, oldTop: Int) {
                logExampleShowEvent()
            }
        })
        logExampleShowEvent()

        binding.ivSelect.setOnClickListener {
            AnalyticsEvents.AC_CHAT_ADD_CLICK.logEvent()
            doShowSelectDialogFragment()
        }

        val firstInstallVersionCode = LocalVersionChecker.getFirstInstallVersionCode()
        if (!MMKV.defaultMMKV().decodeBool(PREF_BOOLEAN_CHAT_GUIDANCE_SHOWED, false)
            && firstInstallVersionCode >= CHAT_GUIDANCE_ADDED_VERSION
        ) {
            showGuidance()
        }
    }


    /**
     * 新增适配新界面的 tabLayout 加ViewPager
     */
    fun initTabLayout() {
        val list = InitUtils.getChatCategory(requireContext())
        list.forEach {
            val tab = binding.layoutParentTopic.newTab()
            binding.layoutParentTopic.addTab(tab)
        }
        val parentAdapter = TopicPageAdapter(requireContext(),list)
        binding.vpChildTopic.adapter = parentAdapter
        binding.layoutParentTopic.setupWithViewPager(binding.vpChildTopic)

    }

    /**
     * 新增获取历史记录的
     */
    fun addRecentHistory() {
        recentViewModel.getAllHistoryMessage()
        recentViewModel.historyMessage.observe(viewLifecycleOwner) {
            historyAdapter.submitList(it)
            if (it.isEmpty()) {
                binding.layoutRecent.isVisible = false
                return@observe
            }
            binding.layoutRecent.isVisible = true
        }
        historyAdapter = ChatHistoryHomeAdapter().apply {
            onMessageDelete = {
                recentViewModel.deleteHistoryMessage(it)
            }

            onMessageClick = {
                AnalyticsEvents.AC_RECENTS_HISTORY_CLICK.logEvent()

                val intent = Intent(requireActivity(), HistoryActivity::class.java).apply {
                    putExtra(HistoryActivity.KEY_HISTORY_DATA, it.messageContent)
                }
                startActivity(intent)
            }

            onDeleteShow = {

            }
        }
        binding.rvRecent.run {
            adapter = historyAdapter
            layoutManager =
                LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
        }
        binding.tvShowRencent.setOnClickListener {
            RecentListActivity.startAction(requireContext())
        }

    }

    override fun onStart() {
        super.onStart()
        if (AiChatApplication.app.isAppForeground() && !isHidden) {
            exampleLoggedList.clear()
        }
        binding.root.post {
            logExampleShowEvent()
        }
    }

    override fun onHiddenChanged(hidden: Boolean) {
        if (!hidden) {
            exampleLoggedList.clear()
            logExampleShowEvent()
        }
        super.onHiddenChanged(hidden)
    }

    private fun doShowSelectDialogFragment(question: String? = null) {
        selectDialogFragment = SelectPhotoBottomDialogFragment().apply {
            listener = object : SelectPhotoBottomDialogFragment.OnPhotoSelectListener {
                override fun onPhotoSelect(uri: String, from: String) {
                    selectDialogFragment?.dismissAllowingStateLoss()
                    context?.let {
                        AnalyticsEvents.AC_CHAT_ADD_SUC.logEvent()
                        val intent = Intent(context, ChatNewActivity::class.java).apply {
                            putExtra(SelectPhotoBottomDialogFragment.KEY_URI, uri)
                            putExtra(SelectPhotoBottomDialogFragment.KEY_PHOTO_FROM, from)
                            question?.let {
                                putExtra(KEY_CHAT_EXAMPLE, it)
                            }
                        }
                        startActivity(intent)
                    }
                }

            }
        }
        selectDialogFragment?.show(childFragmentManager, "")
    }

    private fun logExampleShowEvent() {
        val imageText1 = requireContext().getEnglishString(R.string.example_image_chat_1)
        val text5 = requireContext().getEnglishString(R.string.example_chat_5)
        val text6 = requireContext().getEnglishString(R.string.example_chat_6)
        val text7 = requireContext().getEnglishString(R.string.example_chat_7)
        val text8 = requireContext().getEnglishString(R.string.example_chat_8)

        if (!exampleLoggedList.contains(imageText1) && isViewVisible(binding.exampleImageItem1.root)) {
            AnalyticsEvents.AC_CHAT_EXAMPLE_SHOW.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, imageText1)
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_PIC)
                }
            )
            exampleLoggedList.add(imageText1)
        }

        if (!exampleLoggedList.contains(text5) && isViewVisible(binding.exampleItem5.root)) {
            AnalyticsEvents.AC_CHAT_EXAMPLE_SHOW.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, text5)
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            exampleLoggedList.add(text5)
        }
        if (!exampleLoggedList.contains(text6) && isViewVisible(binding.exampleItem6.root)) {
            AnalyticsEvents.AC_CHAT_EXAMPLE_SHOW.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, text6)
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            exampleLoggedList.add(text6)
        }
        if (!exampleLoggedList.contains(text7) && isViewVisible(binding.exampleItem7.root)) {
            AnalyticsEvents.AC_CHAT_EXAMPLE_SHOW.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, text7)
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            exampleLoggedList.add(text7)
        }
        if (!exampleLoggedList.contains(text8) && isViewVisible(binding.exampleItem8.root)) {
            AnalyticsEvents.AC_CHAT_EXAMPLE_SHOW.logEvent(
                Bundle().apply {
                    putString(AnalyticsParams.KEY_TITLE, text8)
                    putString(AnalyticsParams.KEY_QUS_TYPE, AnalyticsParams.QUS_TYPE_CHAT)
                }
            )
            exampleLoggedList.add(text8)
        }
    }

    private fun loadNativeBanner() {
        if (AiChatApplication.app.appViewModel.isSubscribed()) {
            return
        }

        val adConfig = AdUtils.getMainNativeBannerAdConfig(requireContext())
        oxNativeAdHelper = OxNativeAdHelper.createAd(requireContext(), adConfig.adId)
        oxNativeAdHelper?.run {
            setAdListener(object : NativeAdListener() {
                override fun onAdLoaded() {
                    super.onAdLoaded()
                    showNativeBannerAd()
                }
            })
            loadAd(adConfig.adPlacement)
        }
    }

    private fun showNativeBannerAd() {
        if (!AiChatApplication.app.isAppForeground() || AiChatApplication.app.appViewModel.isSubscribed()) {
            return
        }
        cancelFlashAnimation()
        binding.ivFlash.visibility = View.GONE
        binding.nativeBannerPlaceholder.root.visibility = View.GONE
        binding.itemAds.visibility = View.VISIBLE
        oxNativeAdHelper?.run {
            setViewBinder(
                ViewBinder.Builder()
                    .setLayoutId(R.layout.item_main_native_banner)
                    .setIconId(R.id.ad_icon)
                    .setTitleId(R.id.ad_title)
                    .setBodyId(R.id.ad_body)
                    .setActionId(R.id.ad_action)
                    .setOptionViewId(R.id.ad_options_view)
                    .build()
            )
            showAd(
                binding.nativeAdContainer,
                AdUtils.getMainNativeBannerAdConfig(requireContext()).adPlacement
            )
        }
    }

    private fun playFlashAnimation() {
        flashAnimator = ObjectAnimator.ofFloat(
            binding.ivFlash,
            "translationX",
            0f,
            (binding.nativeBannerPlaceholder.root.width + binding.ivFlash.width).toFloat()
        ).also {
            it.duration = 1800
            it.repeatCount = ValueAnimator.INFINITE
            it.repeatMode = ValueAnimator.RESTART
            it.start()
        }
    }

    private fun cancelFlashAnimation() {
        if (this::flashAnimator.isInitialized) {
            flashAnimator.cancel()
        }
    }

    /**
     * 该 view　是否在屏幕展示超过 2/3
     */
    private fun isViewVisible(view: View): Boolean {
        val rect = Rect()
        view.getLocalVisibleRect(rect)
        val visibleHeight = rect.height().toFloat()
        val totalHeight = view.height.toFloat()
        return visibleHeight / totalHeight >= 0.67
    }

    override fun onDestroyView() {
        oxNativeAdHelper?.destroyAd()
        oxNativeAdHelper = null
        adManager.destroyMainNativeBannerAd()
        super.onDestroyView()
    }

    private fun showGuidance() {
        val binding = DialogChatGuideBinding.inflate(LayoutInflater.from(requireContext()))
        val dialog =
            AlertDialog.Builder(requireContext(), R.style.CustomAlertDialogStyle)
                .setView(binding.root)
                .create()
        dialog.setCancelable(false)
        dialog.show()
        binding.chatInputTipsGotIt.setOnClickListener {
            binding.inputGuideGroup.visibility = View.INVISIBLE
            binding.imgSelectGuideGroup.visibility = View.VISIBLE
        }
        binding.chatImgSelectTipsGotIt.setOnClickListener {
            MMKV.defaultMMKV().encode(PREF_BOOLEAN_CHAT_GUIDANCE_SHOWED, true)
            dialog.dismiss()
        }
        val window = dialog.window
        window?.setGravity(Gravity.BOTTOM)

        val bottomNavigationView = LayoutMainBottomNavigationBinding.inflate(LayoutInflater.from(context)).root

        bottomNavigationView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)

        // 设置 Window 的 padding
        window?.decorView?.setPadding(0, 0, 0, bottomNavigationView.measuredHeight)

        // 获取 Dialog 的 LayoutParams 对象
        val layoutParams = WindowManager.LayoutParams().apply {
            copyFrom(window?.attributes)
            width = WindowManager.LayoutParams.MATCH_PARENT
            height = WindowManager.LayoutParams.WRAP_CONTENT
        }

        // 设置 Dialog 的 LayoutParams
        window?.attributes = layoutParams
    }

    companion object {
        private const val PREF_BOOLEAN_CHAT_GUIDANCE_SHOWED = "boolean_chat_guidance_showed"
    }
}